package com.spr.config;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import static java.util.stream.Collectors.joining;

@Aspect
@Component
@Slf4j
public class HttpAspect {
    @Pointcut("execution(* com.spr.controller..*.*(..)) ")    //扫描包下所有类
    public void pointCut() {
    }
    @Before("pointCut()")
    public void doBefore(JoinPoint joinPoint) {
    }

    @After("pointCut()")
    public void doAfter() {
    }

    @AfterReturning(returning = "object", pointcut = "pointCut()")
    public void doAfterReturning(Object object) {
    }
    @Around("pointCut()")
    public Object doAround(ProceedingJoinPoint joinPoint){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //url
        log.info("请求url={}", request.getRequestURL());
        //method
        log.info("method={}", request.getMethod());
        //ip
        log.info("请求ip={}", request.getRemoteAddr());

        //类方法
        log.info("class_method={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        String paramStr = "";
        try {
            if (request.getMethod().equalsIgnoreCase(RequestMethod.GET.name())) {
                Map<String, String[]> parameterMap = request.getParameterMap();
                Map<String, String> paramMap = new HashMap<>();
                parameterMap.forEach((key, value) ->{
                    if(!"appId".equals(key) && !"appKey".equals(key) && !"token".equals(key)){
                        paramMap.put(key, Arrays.stream(value).collect(joining(",")));
                    }
                });
                paramStr= JSON.toJSONString(paramMap);
            } else {
                paramStr= JSON.toJSONString(joinPoint.getArgs().length == 0 ? "" : joinPoint.getArgs()[0]);
            }
        } catch (Exception e) {
            log.info("入参获取失败 {}",joinPoint.getArgs());
            e.printStackTrace();
        }
        //参数
        log.info("入参 args={}", paramStr);

        try {
            //long startTimeMillis = System.currentTimeMillis();
            Object result = joinPoint.proceed();
            // long execTimeMillis = System.currentTimeMillis() - startTimeMillis;
            log.info("返回结果response={}",result==null ? "" : result);

            return result;
        } catch (Throwable te) {
            log.error(te.getMessage(),te);
            throw new RuntimeException(te.getMessage());
        }
    }

}
